package cn.anlaser.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;

import cn.anlaser.admin.BaseUser;
import cn.anlaser.entity.SimpleEntity;
import cn.anlaser.form.SimpleForm;
import cn.anlaser.page.QueryPage;
import cn.anlaser.page.QuerySpecification;
import cn.anlaser.repository.SimpleRepository;
import cn.anlaser.service.SimpleService;
import cn.anlaser.status.FlagEnum;
import cn.anlaser.utils.BeanMapper;
import cn.anlaser.utils.DynamicSpecifications;


public abstract class SimpleServiceImpl<Form extends SimpleForm, Repository extends SimpleRepository<Entity>, Entity extends SimpleEntity>
		extends CommonServiceImpl<Form, Repository, Entity> implements
		SimpleService<Form, Repository, Entity> {

	@Transactional
	@Override
	public Entity add(Form form) {
		Entity obj = BeanMapper.map(form, getEntityClazz());
		traversalAssign(form, obj);
		return add(obj);
	}

	@Transactional
	@Override
	public Entity add(Entity entity) {
		BaseUser user = userUtils.getUser();
		entity.setCreatedDate(new Date());// DateTime.now());
		entity.setLastModifiedDate(new Date());
		if (user != null) {
			entity.setCreatedBy(user.getId());
		}
		if (entity.getFlag() == null) {// 默认数据，全部有效。新增商品、广告、文章，默认无效，新建时设置
			entity.setFlag(FlagEnum.valid);
		}
		return super.add(entity);
	}

	@Transactional
	@Override
	public Entity edit(Form form) {
		Entity obj = getRepository().findOne(form.getId());
		traversalAssign(form, obj);
		return edit(obj);
	}

	@Transactional
	@Override
	public Entity edit(Entity entity) {
		BaseUser user = userUtils.getUser();
		entity.setLastModifiedDate(new Date());// DateTime.now());
		if (user != null) {
			entity.setLastModifiedBy(user.getId());
		}
		if (entity.getFlag() == null) {// 默认数据，全部有效。新增商品、广告、文章，默认无效，新建时设置
			entity.setFlag(FlagEnum.valid);
		}
		return super.edit(entity);
	}

	@Override
	public List<Entity> findByForm(final Form form) {
		QuerySpecification<Entity> spec = DynamicSpecifications.bySearchFilter(
				buildByForm(form).values(), getEntityClazz());
		if (form.getOrders() == null||form.getOrders().equals("")) {
			form.setOrders("id");
		}
		return getRepository()
				.findAll(
						spec,
						new Sort(form.getDirection(), new String[] { form
								.getOrders() }));
	}

	@Override
	public QueryPage<Entity> findAll(Form form, Pageable pageable) {
		QuerySpecification<Entity> spec = DynamicSpecifications.bySearchFilter(
				buildByForm(form).values(), getEntityClazz());
		QueryPage<Entity> resPage = new QueryPage<Entity>();
		if (form.getOrders() == null||form.getOrders().equals("")) {
			form.setOrders("id");
		}
		resPage.setQueryLine(spec.getQueryLine() + "&size="
				+ pageable.getPageSize() + "&orders=" + form.getOrders()
				+ "&direction=" + form.getDirection());
		resPage.setPage(getRepository().findAll(
				spec,
				new PageRequest(pageable.getPageNumber(), pageable
						.getPageSize(), new Sort(form.getDirection(),
						new String[] { form.getOrders() }))));
		/*
		 * QueryPage<Entity> resPage=(QueryPage<Entity>)getRepository().findAll(
		 * spec, new PageRequest(pageable.getPageNumber(), pageable
		 * .getPageSize(), new Sort(form.getDirection(), new String[] {
		 * form.getOrders() })));
		 */
		return resPage;
	}

	@Transactional
	@Override
	public void logicDelete(Long id) {
		Entity obj = getRepository().findOne(id);
		obj.setFlag(FlagEnum.delete);
		edit(obj);
	}

	@Override
	public Entity findByCodeOne(String code) {
		logger.info(code);
		List<Entity> menus = getRepository().findByCode(code);
		if (menus.size() != 1) {
			if (menus.size() > 1) {
				logger.error(code + " : size() > 1 [" + menus.size() + "]");
				return menus.get(0);
			}
			logger.error(code + " : size() =0 ");
			return null;
		} else {
			return menus.get(0);
		}
	}

	@Override
	public Entity findByNameOne(String name) {
		logger.info(name);
		List<Entity> menus = findsByName(name);
		if (menus.size() != 1) {
			if (menus.size() > 1) {
				logger.error(name + " : size() > 1 [" + menus.size() + "]");
				return menus.get(0);
			}
			logger.error(name + " : size() =0 ");
			return null;
		} else {
			return menus.get(0);
		}
	}

	@Override
	public List<Entity> findsByName(String name) {
		return getRepository().findByName(name);
	}

	@Override
	public Entity findByCode(String code) {
		logger.info(code);
		List<Entity> menus = findsByCode(code);
		if (menus.size() != 1) {
			if (menus.size() > 1) {
				logger.error(code + " : size() > 1 [" + menus.size() + "]");
				return menus.get(0);
			}
			logger.error(code + " : size() =0 ");
			return null;
		} else {
			return menus.get(0);
		}
	}

	@Override
	public List<Entity> findsByCode(String code) {
		return getRepository().findByCode(code);
	}

}
